package com.tony.easymvc.mybatis.core;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.Reader;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.springframework.util.StringUtils;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.io.Files;
import com.tony.easymvc.core.DefaultProjectGenerator;
import com.tony.easymvc.core.FileGenerator;
import com.tony.easymvc.core.bean.ConfigModel;
import com.tony.easymvc.core.bean.ModuleConfig;
import com.tony.easymvc.core.bean.ModuleModel;
import com.tony.easymvc.po.OrMapping;
import com.tony.easymvc.po.ProjectBiz;
import com.tony.easymvc.po.ProjectTables;

public class MapperFileScan {

	private ConfigModel config;

	Charset cs = Charset.forName(FileGenerator.CHARSET);

	public MapperFileScan(ConfigModel config) {
		super();
		this.config = config;
	}

	// public Map<String, List<OrMapping>> doUpdate() throws IOException,
	// JDOMException {
	//// updateMappers();
	//
	//// updatePos();
	// return readMapping();
	//
	// }
	private ProjectBiz biz;

	public Map<String, List<OrMapping>> readMapping(ProjectBiz biz) throws IOException, JDOMException {
		this.biz = biz;
		ModuleModel mm = findModuleModel(biz);

		// ${return config.project.mapperPackage;}.${return biz.bizName}

		String mapperPackage = config.getProject().getMapperPackage() + "." + biz.getBizName();
		String mapperPatht = mapperPackage.replaceAll("\\.", "/");
		String mapperPath = this.config.getParentProjectPath() + "/" + mm.getArtifactId()
				+ DefaultProjectGenerator.resourcesPath + "/" + mapperPatht;

		File mpDir = new File(mapperPath);
		Map<String, List<OrMapping>> dbMapping = Maps.newHashMap();

		File[] files = mpDir.listFiles(new FilenameFilter() {
			public boolean accept(File dir, String name) {
				return name.endsWith("Mapper.xml");
			}
		});
		if (files == null)
			return dbMapping;
		for (int i = 0; i < files.length; i++) {
			// updateXML(files[i]);

			readMapping(files[i], dbMapping);
		}

		return dbMapping;
	}

	private ModuleModel findModuleModel(ProjectBiz biz) {
		ModuleModel mm = null;

		List<ModuleModel> mms = config.getModules().get(ModuleConfig.DAL);
		for (int i = 0; i < mms.size(); i++) {
			mm = mms.get(i);
			if (mm.getBizName().equals(biz.getBizName())) {
				break;
			}
		}
		return mm;
	}

	private void readMapping(File file, Map<String, List<OrMapping>> dbMapping)
			throws FileNotFoundException, JDOMException, IOException {

		SAXBuilder builder = new SAXBuilder();
		Reader read = Files.newReader(file, cs);
		Document document = builder.build(read);
		Element root = document.getRootElement();// 获得根节点
		Element resultMap = root.getChild("resultMap");
		String typevalue = resultMap.getAttributeValue("type");
		String objectName = typevalue.substring(typevalue.lastIndexOf(".") + 1);

		setObjectName(file, objectName);

		/*
		 * System.out.println(objectName);
		 * 
		 */
		List<Element> chs = resultMap.getChildren();
		List<OrMapping> orms = Lists.newArrayList();
		for (int i = 0; i < chs.size(); i++) {
			OrMapping orm = new OrMapping();
			orm.setObjectName(objectName);
			Element tmp = chs.get(i);
			orm.setDbField(tmp.getAttributeValue("column"));
			orm.setJavaField(tmp.getAttributeValue("property"));
			orm.setJdbcType(tmp.getAttributeValue("jdbcType"));
			orm.setPrimaryKey(i == 0);

			fillJDBCType(objectName, orm);

			orms.add(orm);
		}

		dbMapping.put(objectName, orms);

		read.close();
	}

	private void setObjectName(File file, String objectName) throws IOException {
		List<String> lines = Files.readLines(file, cs);
		for (String line : lines) {
			if (StringUtils.isEmpty(line))
				continue;
			if (line.contains("from ")) {
				String[] arr = line.split("\\s+");
				boolean flag = false;
				String tableName = null;
				for (String token : arr) {
					if (flag) {
						tableName = token;
						break;
					}
					if (token.equals("from")) {
						flag = true;
					}
				}
				
				List<ProjectTables> projectTables =  biz.getProjectTables();
				for(ProjectTables projectTable : projectTables) {
					if(projectTable.getTableName().equals(tableName)) {
						projectTable.setObjectName(objectName);
						break;
					}
				}
				break;
			}
		}

	}

	private void fillJDBCType(String objectName, OrMapping orm) throws IOException {

		String poPackage = config.getProject().getMapperPackage() + "." + biz.getBizName();
		String poPatht = poPackage.replaceAll("\\.", "/");
		String poPath = this.config.getParentProjectPath() + "/"
				+ this.config.getModules().get(ModuleConfig.PO).get(0).getArtifactId()
				+ DefaultProjectGenerator.SRC_MAIN_JAVA + "/" + poPatht;

		File poJavaFile = new File(poPath + "/" + objectName + ".java");
		List<String> tempitem = Files.readLines(poJavaFile, cs);
		for (int k = 0; k < tempitem.size(); k++) {
			String line = tempitem.get(k);
			if (line.trim().startsWith("private") && line.contains(orm.getJavaField())) {
				String arr[] = line.trim().split("\\s+");
				String type = arr[1];
				// System.out.println(type);
				orm.setJdbcType(type.toUpperCase());
			}
		}
	}

	public static void main(String[] a) {
		String line = "	    private Date createDate;";

		System.out.println(line.trim().startsWith("private"));

		String s[] = line.trim().split("\\s");
		System.out.println(s.length);

	}

	// private void updateXML(File file) throws IOException {
	// List<String> lines = Files.readLines(file, cs);
	// List<String> newTmplines = Lists.newArrayList();
	// boolean flag = false;
	// int insertLine = -1;
	// for (int i = 0; i < lines.size(); i++) {
	// String line = lines.get(i);
	// String token = "id=\"selectByPrimaryKey\"";
	// if (line.contains(token)) {
	// flag = true;
	// String newline = line.replace(token,
	// "id=\"selectBySql\"").replace("java.lang.Integer",
	// "java.lang.String");
	// newTmplines.add(newline);
	// } else if (flag && line.trim().startsWith("where")) {
	// newTmplines.add("\t\twhere ${whereSql}");
	// newTmplines.add("\t</select>");
	// flag = false;
	// } else if (flag) {
	// newTmplines.add(line);
	// } else if (line.trim().startsWith("</mapper>")) {
	// insertLine = i;
	// }
	// }
	// lines.addAll(insertLine, newTmplines);
	// BufferedWriter writer = Files.newWriter(file, cs);
	// for (
	//
	// int i = 0; i < lines.size(); i++) {
	// writer.write(lines.get(i));
	// writer.newLine();
	// }
	// writer.flush();
	// writer.close();
	//
	// }

	// private void updateMappers() throws IOException {
	// String mapperPath = this.config.getMapperPath();
	// File mpDir = new File(mapperPath);
	// File[] files = mpDir.listFiles(new FilenameFilter() {
	// public boolean accept(File dir, String name) {
	// return name.endsWith("Mapper.java");
	// }
	// });
	// if (files == null)
	// return;
	// for (int i = 0; i < files.length; i++) {
	// updateMapper(files[i]);
	// }
	//
	// }

	// private void updatePos() throws IOException {
	// String poPath = this.config.getPoPath();
	// File mpDir = new File(poPath);
	// File[] files = mpDir.listFiles(new FilenameFilter() {
	// public boolean accept(File dir, String name) {
	// return !name.endsWith("Example.java");
	// }
	// });
	// if (files == null)
	// return;
	// for (int i = 0; i < files.length; i++) {
	// File tempPoFile = files[i];
	// //System.out.println(tempPoFile.getName());
	// BufferedReader reader = new BufferedReader (new InputStreamReader(new
	// FileInputStream(tempPoFile),"gbk") );
	// String sum = "",line = null;
	// while((line = reader.readLine())!=null) {
	// sum += line + "\r\n";
	// }
	// reader.close();
	//
	// BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new
	// FileOutputStream(tempPoFile),"utf-8"));
	// writer.write(sum);
	// writer.flush();
	// writer.close();
	// }
	//
	// }

	// private void updateMapper(File file) throws IOException {
	// List<String> lines = Files.readLines(file, cs);
	// String newline = "";
	// for (int i = 0; i < lines.size(); i++) {
	// String line = lines.get(i);
	// String token = "selectBy";
	// if (line.contains(token)) {
	// int a = line.indexOf(token);
	// a = a + token.length();
	// String temp = line.substring(0, a);
	// newline = temp + "Sql(@Param(\"whereSql\")String whereSql);";
	// break;
	// }
	// }
	// for (int i = lines.size() - 1; i >= 0; i--) {
	// String line = lines.get(i);
	// if (line.trim().equals("}")) {
	// lines.add(i, newline);
	// lines.add(i, "\t@ReadOnly");
	// lines.add(i, "\r\n");
	//
	// break;
	// }
	// }
	// BufferedWriter writer = Files.newWriter(file, cs);
	// for (int i = 0; i < lines.size(); i++) {
	// writer.write(lines.get(i));
	// writer.newLine();
	// }
	// writer.flush();
	// writer.close();
	// }
}
